package tuling.EalyAopZskDemo;

import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.context.annotation.Bean;

/**
 * Created by xsls on 2019/6/10.
 * <p>
 * * Spring常见代理创建方式
 * * FactoryBean方式，创建单个动态代理： ProxyFactoryBean  1.指定续增强的接口:proxyInterfaces  2.指定需增强的实现类target   3.指定Advice、Advisor、Interceptor都行
 * * autoProxy方式：批量根据advisor自动创建
 * * BeanPostProcessor手动指定Advice方式  BeanNameAutoProxyCreator  1.指定Advice  2.可以使用正则来匹配 bean 的名字
 * * BeanPostProcessor自动扫描Advisor方式  DefaultAdvisorAutoProxyCreator  (不支持注解)、
 * *         AnnotationAwareAspectJAutoProxyCreator（注解）、
 * *         AspectJAwareAdvisorAutoProxyCreator（XML）
 */
// @EnableAspectJAutoProxy(exposeProxy = true)
public class EalyAopZksConfig {

	// 被代理对象
	@Bean
	public Calc calc() {
		return new Calc();
	}

	// Advice 方式
	@Bean
	public AdviceLog adviceLog() {
		return new AdviceLog();
	}

	// Interceptor方式 ， 类似环绕通知
	@Bean
	public InterceptorLog interceptorLog() {
		return new InterceptorLog();
	}

	// Interceptor方式 ， 类似环绕通知
	@Bean
	public InterceptorLog2 interceptorLog2() {
		return new InterceptorLog2();
	}


	// ---------------------方式1--------------------
	/**
	 * FactoryBean方式单个： ProxyFactoryBean
	 *
	 * @return
	 */
	// @Bean
	// public ProxyFactoryBean calcProxy() {
	// 	ProxyFactoryBean userService = new ProxyFactoryBean();
	// 	userService.setInterceptorNames("adviceLog", "interceptorLog");  // 根据指定的顺序执行
	// 	userService.setTarget(calc());
	// 	return userService;
	// }



	// ---------------------方式2--------------------


	/**
	 * Advisor 种类很多：
	 * RegexpMethodPointcutAdvisor 按正则匹配类
	 * NameMatchMethodPointcutAdvisor 按方法名匹配
	 * DefaultBeanFactoryPointcutAdvisor xml解析的Advisor   <aop:before
	 * InstantiationModelAwarePointcutAdvisorImpl  注解解析的advisor(@Before @After....)
	 * @return
	 * */
	// @Bean
	// public NameMatchMethodPointcutAdvisor nameMatchAdvisor() {
	//     NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor();
	//     // 通知(Advice)  ：是我们的通知类
	//     // 通知者(Advisor)：是经过包装后的细粒度控制方式。
	//     advisor.setAdvice(adviceLog());
	//     advisor.setMappedNames("add");
	//     return  advisor;
	// }
	// @Bean
	// public ProxyFactoryBean calcProxy() {
	// 	ProxyFactoryBean userService = new ProxyFactoryBean();
	// 	userService.setInterceptorNames("nameMatchAdvisor");  // 根据指定的顺序执行
	// 	userService.setTarget(calc());
	// 	return userService;
	// }


	// ---------------------方式3--------------------
	/**
	 *     autoProxy: BeanPostProcessor手动指定Advice方式  BeanNameAutoProxyCreator
	 * @return
	 */

	@Bean
	 public BeanNameAutoProxyCreator autoProxyCreator() {
	 BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
	 //设置要创建代理的那些Bean的名字
	 beanNameAutoProxyCreator.setBeanNames("calc");
	 //设置拦截链名字(这些拦截器是有先后顺序的)
	 beanNameAutoProxyCreator.setInterceptorNames("interceptorLog", "adviceLog", "interceptorLog2");

	 return beanNameAutoProxyCreator;
	 }
	/**
	 * BeanPostProcessor自动扫描Advisor方式  DefaultAdvisorAutoProxyCreator
	 * @return
	 */
	// @Bean
	// public DefaultAdvisorAutoProxyCreator autoProxyCreator() {
	// 	return new DefaultAdvisorAutoProxyCreator();
	// }

}
